package liming.tool.encryption;

import java.util.LinkedHashSet;
import java.util.Random;
import java.util.Set;

/**
 * 基于指定字符集生成随机字符串的工具类
 */
public class RandomStringGenerator {
    // 存储去重后的有效字符集（保留插入顺序）
    String randomString;
    // 带种子的随机数生成器
    Random random;

    /**
     * 构造随机字符串生成器
     * <p>通过LinkedHashSet实现字符去重和顺序保留的双重特性</p>
     *
     * @param seed          随机数种子，相同种子保证可重复的随机序列
     * @param randomString  原始字符集（允许包含重复字符）
     */
    public RandomStringGenerator(long seed, String randomString) {
        // 使用LinkedHashSet进行去重处理（时间复杂度O(n)）
        Set<Character> characters = new LinkedHashSet<>();
        for (int i = 0; i < randomString.length(); i++)
            characters.add(randomString.charAt(i));

        // 重建无重复字符的字符串
        StringBuilder sb = new StringBuilder();
        characters.forEach(sb::append);
        this.randomString = sb.toString();

        // 初始化带种子的随机数生成器
        this.random = new Random(seed);
    }

    /**
     * 生成指定长度的随机字符串
     * <p>注意：由于使用伪随机数算法，不同实例或相同种子可能产生重复序列</p>
     *
     * @param length  需要生成的字符串长度（需大于0）
     * @return        生成的随机字符串（可能包含重复模式）
     * @throws IllegalArgumentException 如果length小于1时抛出异常
     */
    public String generate(int length) {
        // 参数校验（隐式依赖调用方保证有效性）
        if (length < 1) throw new IllegalArgumentException("Length must be positive");

        // 构建随机字符串（时间复杂度O(n)）
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            // 从有效字符集中随机选取字符
            int index = random.nextInt(randomString.length());
            sb.append(randomString.charAt(index));
        }
        return sb.toString();
    }
}